﻿/*
 *  VnKeyboard JavaScript Vietnamese Input Method Source File
 *  Dated: 28-07-2008
 *  Author: Tienbv - tienbv@outlook.com
 *	Copyright (C) 2014 tienbv.name.vn
 *	Website:	tienbv.name.vn
 *  License: GPL
 *	You are allowed to use this software in any way you want providing:
 *		1. You must retain this copyright notice at all time
 *		2. You must not claim that you or any other third party is the author
 *		   of this software in any way.
 * 
 * 
 * Description:
 *  Kỹ thuật xử lý từ:
 *      - Xác định từ gần nhất và chỉ xử lý trên từ đó
 * 
 * 
 * 
*/

(function (win, undefined, cookie) {

    "use strict";

    //#region Private Fields

    // Get: kiểu gõ
    var types = {
        TELEX: 1,
        VNI: 2,
        VIQR: 3
    };

    // Bảng mã
    var keycodes = {
        Tcvn: 1,
        Unicode: 2
    };

    var cookieName = {
        typing: "VNKeyboard_Typing",
        showControl: "VNKeyboard_showControl",
        isUsingOldAccent: "VNKeyboard_usingOldAccent",
        active: "VNKeyboard_active",
        hasCheckSpelling: "VNKeyboard_checkSpelling",
    };

    // Các config của keyboard
    var config = {
        useCookie: true,
        type: types.TELEX,
        isUsingOldAccent: true,
        domain: _getDomain(),
        showControlPanel: false,
        nav: navigate.userAgent.toLowerCase()
    };

    //#endregion
    var VNKEYBOARD = function (option) {
        /// <summary>
        /// Bộ gõ tiếng việt 
        /// </summary>

        if (!this.isSupport()) {
            throw "Trình duyệt bạn đang xử dụng không hỗ trợ Gõ Tiếng Việt. Vui lòng sử dụng trình duyệt mới hơn.";
        }

        this.config = config;
        this.isIE = _isUsingIE();

        // Giá trị xác định Bộ gõ có được phép hoạt động hay không.
        this.active;

        // Key vừa được nhấn
        this.code;

        // Html element đang focus
        this.target;

        // Chuỗi các ký tự gõ liền nhau thì sinh dấu mũ ( :| ). Ví dụ: a, e, o, d, w. Tương ứng với mỗi kiểu gõ thì các ký tự khác nhau.
        this.doubleChar;

        // Mảng các ký tự doublechar
        this.uni;

        this._configuration();
        this.init();
    };

    VNKEYBOARD.prototype.init = function () {
        /// <summary>
        /// Private: Khởi tạo bộ gõ.
        /// </summary>

        if (this.active) {
            _addEventHandle("keypress", this._keypressHandler, true);
        }
        else {
            _addEventHandle("keypress", function () { }, true);
        }

        return this;
    };

    VNKEYBOARD.prototype.enable = function () {
        /// <summary>
        /// Ctrl + Shift: Kích hoạt bộ gõ.
        /// </summary>
        this.active = true;
        this.init();
    };

    VNKEYBOARD.prototype.disable = function () {
        /// <summary>
        /// Ctrl + shift: Bỏ kích hoạt bộ gõ.
        /// </summary>
        this.active = false;
        this.init();
    };

    VNKEYBOARD.prototype.setType = function (type) {
        /// <summary>
        /// Thiết lập kiểu gõ
        /// </summary>
        /// <param name="type">Kiểu gõ: Telex, VNI, VNQR</param>

    };

    VNKEYBOARD.prototype.isSupport = function () {
        /// <summary>
        /// Kiểm tra môi trường đang sử dụng có hỗ trợ GTV không.
        /// </summary>
        var result = false;

        return result;
    };

    VNKEYBOARD.prototype._configuration = function () {
        /// <summary>
        /// Thiết lập bộ gõ
        /// </summary>
        this.active = _getCookie(cookieName.active, true);

        // Kiểu bỏ dấu cũ hoặc mới: kiểu cũ (òa, òe, ùy), kiểu mới (oà, oè, uỳ);
        // Mặc định dùng kiểu mới.
        this.config.isUsingOldAccent = _getCookie(cookieName.isUsingOldAccent, false);

        this._setTyping();
    };

    VNKEYBOARD.prototype._setTyping = function () {
        /// <summary>
        /// Thiết lập kiểu gõ.
        /// </summary>

        // Lấy kiểu gõ trong cookie
        // Luôn mặc định là Telex nếu trong cookie không tồn tại (tương ứng với khởi tạo lần đầu tiên).
        this.config.type = _getCookie(cookieName.typing, types.TELEX);

        switch (this.config.type) {
            case types.VNI:
                this.uni = ["9", "6", "6", "6", "7", "8"];
                this.doubleChar = "6789";
                break;
            case types.VIQR:
                this.uni = ["D", "^", "^", "^", "+", "("];
                this.doubleChar = "D^+(";
                break;
            default:
                // Mặc định là Telex
                this.uni = ["D", "A", "E", "O", "W", "W"];
                this.doubleChar = "DAWEO";
                break;
        }
    };

    VNKEYBOARD.prototype._keypressHandler = function (e) {
        /// <summary>
        /// Hàm xử lý phím nhập vào.
        /// </summary>
        /// <param name="e">Keypress event</param>

        this._getKeyAndTarget(e);
        if (this._isValid(e)) {
            this.char = _getChar(this.code);

            this.process();
        }
    };

    VNKEYBOARD.prototype.process = function () {
        /// <summary>
        /// Xử lý gõ tiếng việt
        /// </summary>


    }

    VNKEYBOARD.prototype._isValid = function (e) {
        /// <summary>
        /// Kiểm tra các điều kiện cho phép xử lý tiếng việt.
        /// </summary>
        /// <param name="e">Keypress event</param>
        /// <returns type="boolean">Giá trị xác định có xử lý tiếng việt tiếp hay không.</returns>

        var result = true;
        // Đang nhấn phím Ctrl
        if (e.ctrlKey) {
            result = false;
        }

        // Đang nhấn Alt + left, Alt + Right, Alt + ~
        if (e.altKey && (this.code != 92) && (this.code != 91) && (this.code != 126)) {
            result = false;
        }

        // Control đang focus không phải là control nhập liệu
        if (!this._isInputControl()) {
            result = false;
        }

        return result;
    }

    VNKEYBOARD.prototype._getKeyAndTarget = function (e) {
        /// <summary>
        /// Lấy charcode và target control đang focus.
        /// </summary>
        /// <param name="e">Keypress event</param>

        if (this.isIE) {
            this.target = window.event.srcElement;
            this.code = window.event.keyCode;
        }
        else {
            this.target = e.target;
            this.code = e.which;
        }
    }

    VNKEYBOARD.prototype._isInputControl = function () {
        /// <summary>
        /// Kiểm tra target hiện tại có phải là thẻ cho phép nhập nội dung hay không.
        /// </summary>
        /// <returns type=""></returns>
        var result = false;
        if (this.target.type === "text" || this.target.type === "textarea") {
            result = true;
        }

        if (this.target.getAttribute("contenteditable")) {
            result = true;
        }

        return result;

    }

    //#region Private Methods

    var _getType = function (type) {
        /// <summary>
        /// Trả về kiểu gõ từ người dùng truyền vào.
        /// </summary>
        /// <param name="type" type="string">Kiểu gõ được truyền</param>

        // Kiểu gõ mặc định
        var result = types.TELEX;

        if (typeof type === "string") {
            type = type.toLowerCase();
            if (type === "vni") {
                result = types.VNI;
            }
            else if (type === "vnqr") {
                result = types.VIQR;
            }
        }

        return result;
    };

    var _getDomain = function (domain) {
        /// <summary>
        /// Trả về domain của site được nhúng
        /// </summary>
        /// <param name="domain">Domain tự gán</param>
        /// <returns type=""></returns>
        var result = document.domain;
        if (result !== "" || result !== undefined) {
            result = domain;
        }
        return result;
    };

    var _isSupportIE = function () {
        /// <summary>
        /// Kiểm tra phiên bản IE đang dùng có hỗ trợ hay không.
        /// </summary>

        var result = true;

        return result;
    };

    var _addEventHandle = function (event, callback, useCapture) {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="event"></param>
        /// <param name="callback"></param>
        /// <param name="useCapture"></param>
        if (_isUsingIE()) {
            document.attachEvent("on" + event, callback);
        } else {
            document.addEventListener(event, callback, useCapture);
        }
    };

    var _isUsingIE = function () {
        /// <summary>
        /// Trả về giá trị xác định trình duyệt đang sử dụng có phải là IE hay không.
        /// </summary>
        /// <returns type="boolean">true: đang sử dụng IE, false: sử dụng trình duyệt khác.</returns>
        return navigator.userAgent.toLowerCase().indexOf("msie") > 0;
    };

    var _getChar = function (code) {
        /// <summary>
        /// Trả về ký tự từ mã code
        /// </summary>
        /// <param name="code">mã code</param>
        /// <returns type="char">Ký tự trả về</returns>
        return String.fromCharCode(code);
    };

    var _setCookie = function (key, value) {
        /// <summary>
        /// Thêm cookie, mặc định lưu trong 365 ngày.
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="value">Giá trị</param>

        var date = new Date();
        var exdays = 365; // Set trong 365 ngày
        date.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
        var expires = "expires=" + date.toUTCString();
        cookie = key + "=" + value + "; " + expires;
    };

    var _getCookie = function (key, defaults) {
        /// <summary>
        /// Trả về giá trị của cookie theo key
        /// </summary>
        /// <param name="key">Key của cookie cần lấy</param>
        /// <param name="defaults">Giá trị mặc định trả về nếu key không tồn tại.</param>
        /// <returns type="string">Giá trị tương ứng.</returns>
        var name = key + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') {
                c = c.substring(1);
            }
            if (c.indexOf(name) != -1) {
                return c.substring(name.length, c.length);
            }
        }
        return defaults === undefined ? "" : defaults;
    };

    //#endregion

    new VNKEYBOARD({});
})
(window, undefined, document.cookie)